package com.yixin.ystartlibrary.utils;

import android.annotation.TargetApi;
import android.app.Activity;
import android.app.ActivityManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.Build;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.view.Gravity;
import android.view.inputmethod.InputMethodManager;
import android.widget.TextView;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * User: Luozi
 * Date: 2015-05-22
 * Content 工具类:
 */
public class Utils {

    public static final boolean DEBUG = true;

    private static final String MOBILE_REGEX = "^0?[1][34578][0-9]{9}$";

    /**
     * 屏幕宽度,单位像素(px).
     *
     * @param context application
     * @return int
     */
    public static int getWidth(Context context) {
        DisplayMetrics displayMetrics = getDisplayMetrics(context);
        return displayMetrics.widthPixels;
    }

    /**
     * 屏幕高度,单位像素(px).
     *
     * @param context application
     * @return int
     */
    public static int getHeight(Context context) {
        DisplayMetrics displayMetrics = getDisplayMetrics(context);
        return displayMetrics.heightPixels;
    }

    // 屏幕像素对象
    private static DisplayMetrics getDisplayMetrics(Context context) {
        return context.getResources().getDisplayMetrics();
    }

    /**
     * 重启APP，并且打开一个activity
     *
     * @param activity
     * @param cls
     */
    public static void restartIntent(Activity activity, Class<?> cls) {
        Intent intent = new Intent(activity, cls);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
        activity.startActivity(intent);
        activity.finish();
    }

    /**
     * 启动一个activity
     */
    public static void startIntent(Activity activity, Class<?> cls) {
        Intent intent = new Intent(activity, cls);
        activity.startActivity(intent);
    }

    /**
     * 检测是否安装相应分享应用.
     */
    public static boolean isAvailable(Context context, String packageName) {
        PackageManager packageManager = context.getPackageManager();

        List<PackageInfo> info = packageManager.getInstalledPackages(0);
        for (int i = 0; i < info.size(); i++) {
            if ((info.get(i)).packageName.equalsIgnoreCase(packageName))
                return true;
        }
        return false;
    }

    /**
     * 关闭软键盘.
     */
    public static void closeInput(Activity activity) {
        ((InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE))
                .hideSoftInputFromWindow(
                        activity
                                .getCurrentFocus()
                                .getWindowToken(),
                        InputMethodManager.HIDE_NOT_ALWAYS);
    }

    /**
     * 根据图片的名称获取对应的资源id.
     */
    public static int getDrawResourceID(Context context, String folderName, String resourceName) {
        Resources res = context.getResources();
        int picid = res.getIdentifier(resourceName, folderName, context.getPackageName());
        return picid;
    }

    /**
     * Gson数据解析到javaBean.
     */
    public static <T> T getGsonToModel(String data) {
        TypeToken<T> typeToken = new TypeToken<T>() {
        };
        return new Gson().fromJson(data, typeToken.getType());
    }

    /**
     * unicode转换为中文
     */
    public static String decodeUnicode(String theString) {

        char aChar;

        int len = theString.length();

        StringBuffer outBuffer = new StringBuffer(len);

        for (int x = 0; x < len; ) {

            aChar = theString.charAt(x++);

            if (aChar == '\\') {

                aChar = theString.charAt(x++);

                if (aChar == 'u') {

                    // Read the xxxx

                    int value = 0;

                    for (int i = 0; i < 4; i++) {

                        aChar = theString.charAt(x++);

                        switch (aChar) {

                            case '0':

                            case '1':

                            case '2':

                            case '3':

                            case '4':

                            case '5':

                            case '6':
                            case '7':
                            case '8':
                            case '9':
                                value = (value << 4) + aChar - '0';
                                break;
                            case 'a':
                            case 'b':
                            case 'c':
                            case 'd':
                            case 'e':
                            case 'f':
                                value = (value << 4) + 10 + aChar - 'a';
                                break;
                            case 'A':
                            case 'B':
                            case 'C':
                            case 'D':
                            case 'E':
                            case 'F':
                                value = (value << 4) + 10 + aChar - 'A';
                                break;
                            default:
                                throw new IllegalArgumentException(
                                        "Malformed   \\uxxxx   encoding.");
                        }

                    }
                    outBuffer.append((char) value);
                } else {
                    if (aChar == 't')
                        aChar = '\t';
                    else if (aChar == 'r')
                        aChar = '\r';

                    else if (aChar == 'n')

                        aChar = '\n';

                    else if (aChar == 'f')

                        aChar = '\f';

                    outBuffer.append(aChar);

                }

            } else

                outBuffer.append(aChar);

        }

        return outBuffer.toString();

    }


    /**
     * Loads an integer array asset into a list.
     *
     * @param r      Resources
     * @param resNum arrays.xml 资源
     * @return ArrayList
     */
    public static ArrayList<Integer> loadIntegerArray(Resources r, int resNum) {
        int[] vals = r.getIntArray(resNum);
        int size = vals.length;
        ArrayList<Integer> list = new ArrayList<>(size);

        for (int i = 0; i < size; i++) {
            list.add(vals[i]);
        }

        return list;
    }

    /**
     * Loads a String array asset into a list.
     *
     * @param r      Resources
     * @param resNum arrays.xml 资源
     * @return ArrayList
     */
    public static ArrayList<String> loadStringArray(Resources r, int resNum) {
        String[] labels = r.getStringArray(resNum);
        ArrayList<String> list = new ArrayList<>(Arrays.asList(labels));
        return list;
    }

    /**
     * dp 计算换算成像素
     *
     * @param context application
     * @param dp      dp
     * @return 像素int
     */
    public static int dp2px(Context context, int dp) {
        float density = context.getResources().getDisplayMetrics().density;
        return Math.round((float) dp * density);
    }

    /**
     * 设置TextView的drawable数据.
     *
     * @param activity
     * @param resId    图片资源
     * @param view     view
     * @param gravity  方向
     */
    public static void setCompoundDrawables(Activity activity, int resId, TextView view, int gravity) {
        Drawable drawable = activity.getResources().getDrawable(resId);
        if (drawable == null)
            throw new NullPointerException("找不到 resId ＝ " + resId + ",无法构建drawable");
        drawable.setBounds(0, 0, drawable.getMinimumWidth(), drawable.getMinimumHeight());
        Drawable left = null, right = null, top = null, bottom = null;
        if (gravity == Gravity.LEFT || gravity == Gravity.START) {
            left = drawable;
        } else if (gravity == Gravity.RIGHT || gravity == Gravity.END) {
            right = drawable;
        } else if (gravity == Gravity.TOP) {
            top = drawable;
        } else if (gravity == Gravity.BOTTOM) {
            bottom = drawable;
        }
        view.setCompoundDrawables(left, top, right, bottom);
    }


    /**
     * Passed to function:
     * lat1, lon1 = Latitude and Longitude of point 1 (in decimal degrees)
     * lat2, lon2 = Latitude and Longitude of point 2 (in decimal degrees)
     * unit = the unit you desire for results
     * where: 'M' is statute miles (default)
     * 'K' is kilometers
     * 'N' is nautical miles
     */
    public static double distance(double lat1, double lon1, double lat2, double lon2, String unit) {
        double theta = lon1 - lon2;
        double dist = Math.sin(deg2rad(lat1)) * Math.sin(deg2rad(lat2)) + Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) * Math.cos(deg2rad(theta));
        dist = Math.acos(dist);
        dist = rad2deg(dist);
        dist = dist * 60 * 1.1515;
        if (unit == "K") {
            dist = dist * 1.609344;
        } else if (unit == "N") {
            dist = dist * 0.8684;
        }

        return (dist);
    }

    /**
     * This function converts decimal degrees to radians.
     */
    private static double deg2rad(double deg) {
        return (deg * Math.PI / 180.0);
    }

    /**
     * This function converts radians to decimal degrees.
     */
    private static double rad2deg(double rad) {
        return (rad * 180 / Math.PI);
    }

    /**
     * 取小数点,四舍五入后.
     */
    public static String formatDouble(double str, int count) {
        BigDecimal bd = new BigDecimal(str);
        bd = bd.setScale(count, BigDecimal.ROUND_HALF_UP);
        return bd.toString();
    }

    /**
     * 取小数点,四舍五入后.
     */
    public static String formatDouble(float str, int count) {
        BigDecimal bd = new BigDecimal(str);
        bd = bd.setScale(count, BigDecimal.ROUND_HALF_UP);
        return bd.toString();
    }

    /**
     * 取小数点,四舍五入后.
     */
    public static float formatFloat(float str, int count) {
        BigDecimal bd = new BigDecimal(str);
        bd = bd.setScale(count, BigDecimal.ROUND_HALF_UP);
        return bd.floatValue();
    }

    /**
     * 拨打电话
     *
     * @param activity Activity
     * @param phone    电话号码
     */
    public static void call(Activity activity, String phone) {
        Intent intent = new Intent();
        intent.setAction(Intent.ACTION_CALL);
        intent.setData(Uri.parse("tel:" + phone));
        activity.startActivity(intent);
    }

    /**
     * 调用拨号键盘
     *
     * @param activity Activity
     * @param phone    电话号码
     */
    public static void callDialPad(Activity activity, String phone) {
        Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:" + phone));
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        activity.startActivity(intent);
    }

    /**
     * 验证手机号
     *
     * @param mobiles 手机号码
     * @return Ture is phone,false is other.
     */
    public static boolean isMobile(String mobiles) {
        Pattern p = Pattern.compile(MOBILE_REGEX);
        Matcher m = p.matcher(mobiles);
        return m.matches();
    }

    /**
     * 获取组合数据,a,b,c to abc;
     *
     * @param val 数据集
     * @return String.
     */
    public static String getCombinationValue(Object... val) {
        if ((val == null) || (val.length == 0)) {
            return null;
        }

        StringBuilder sb = new StringBuilder();
        for (Object v : val) {
            sb.append(v);
        }
        return sb.toString();
    }

    /**
     * 判断当前网络是否可用.
     *
     * @param context From application.
     * @return Return boolean, true is network. false is no network.
     */
    public static boolean isNetworkAvailable(Context context) {
        ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        if (connectivityManager == null) {
            return false;
        } else {
            NetworkInfo[] networkInfo = connectivityManager.getAllNetworkInfo();

            if (networkInfo != null && networkInfo.length > 0) {
                for (int i = 0; i < networkInfo.length; i++) {
                    if (networkInfo[i].getState() == NetworkInfo.State.CONNECTED) {
                        return true;
                    }
                }
            }
        }
        return false;
    }

    /**
     * 加载json文件.
     *
     * @param jsonName eg: xxx.json
     */
    public static String loadJsonFromAsset(Context context, String jsonName) {
        String json;
        try {
            InputStream is = context.getAssets().open(jsonName);
            int size = is.available();
            byte[] buffer = new byte[size];
            is.read(buffer);
            is.close();
            json = new String(buffer, "UTF-8");
        } catch (IOException ex) {
            LogUtils.e("json读取出错了," + ex.toString());
            return null;
        }
        return json;

    }

    /**
     * 启动activity,如果该activity已经启动,则直接打开;如果该activity没有启动,则从新启动.
     * 一般用于状态栏点击进入程序时使用.
     *
     * @param context
     * @param cls     被启动的activity
     */
    public static Intent startTaskIntent(Context context, Class<?> cls) {
        if (Build.VERSION.SDK_INT >= 21) {
            return startNewApiTaskIntent(context, cls);
        } else {
            return startOldApiTaskIntent(context, cls);
        }
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    private static Intent startNewApiTaskIntent(Context context, Class<?> cls) {
        final PackageManager pm = context.getPackageManager();
        final ActivityManager am = (ActivityManager)
                context.getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.AppTask> appTasks = am.getAppTasks();
        for (ActivityManager.AppTask task : appTasks) {
            final ActivityManager.RecentTaskInfo info = task.getTaskInfo();
            Intent intent = new Intent(info.baseIntent);
            if (info.origActivity != null) {
                intent.setComponent(info.origActivity);
            }
            final ResolveInfo resolveInfo = pm.resolveActivity(intent, 0);
            if (resolveInfo != null) {
                final ActivityInfo activityInfo = resolveInfo.activityInfo;
                if (TextUtils.equals(activityInfo.packageName, context.getPackageName())) {
                    return intent;
                }
            }
        }

        Intent intent = new Intent(context, cls);
        intent.setFlags((intent.getFlags() & ~Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED)
                | Intent.FLAG_ACTIVITY_NEW_TASK);

        return intent;
    }

    private static Intent startOldApiTaskIntent(Context context, Class<?> cls) {
        final PackageManager pm = context.getPackageManager();
        final ActivityManager am = (ActivityManager)
                context.getSystemService(Context.ACTIVITY_SERVICE);

        final List<ActivityManager.RecentTaskInfo> recentTasks = am.getRecentTasks(20, 0x0002);
        for (ActivityManager.RecentTaskInfo info : recentTasks) {
            Intent intent = new Intent(info.baseIntent);
            if (info.origActivity != null) {
                intent.setComponent(info.origActivity);
            }
            final ResolveInfo resolveInfo = pm.resolveActivity(intent, 0);
            if (resolveInfo != null) {
                final ActivityInfo activityInfo = resolveInfo.activityInfo;
                if (TextUtils.equals(activityInfo.packageName, context.getPackageName())) {
                    context.startActivity(intent);
                    return intent;
                }
            }
        }

        Intent intent = new Intent(context, cls);
        intent.setFlags((intent.getFlags() & ~Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED)
                | Intent.FLAG_ACTIVITY_NEW_TASK);
        return intent;
    }

    /**
     * 判断集合是否为空
     *
     * @param c 集合
     * @param <V> 泛型
     * @return 为空的时候为true
     */
    public static <V> boolean isEmpty(Collection<V> c) {
        return (c == null || c.size() == 0);
    }

    /***
     * 判断 String 是否是 整数（包含正负数）
     *
     * @param input text
     * @return 是整型的时候返回true
     */
    public static boolean isNumber(String input) {
        Matcher mer = Pattern.compile("^[+-]?[0-9]+$").matcher(input);
        return mer.find();
    }

    /***
     * 判断 String 是否是 数字（包含正负数）
     *
     * @param input text
     * @return 是数字的时候返回true
     */
    public static boolean isNumberDecimal(String input) {
        Matcher mer = Pattern.compile("^[+-]?[0-9]+.?[0-9]+").matcher(input);
        return mer.find();
    }

    public static String checkTextNull(String s) {
        if (TextUtils.isEmpty(s) || TextUtils.equals("null", s)) {
            return "";
        }
        return s;
    }

    public static boolean isTextNull(String s) {
        return TextUtils.isEmpty(s) || TextUtils.equals("null", s);
    }

    /**
     * 判断某个界面是否在前台
     *
     * @param context
     * @param className 某个界面名称
     */
    public static boolean isForeground(Context context, String className) {
        if (context == null || TextUtils.isEmpty(className)) {
            return false;
        }

        ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.RunningTaskInfo> list = am.getRunningTasks(1);
        if (list != null && list.size() > 0) {
            ComponentName cpn = list.get(0).topActivity;
            if (className.equals(cpn.getClassName())) {
                return true;
            }
        }
        return false;
    }




}
